/*
 * Copyright (C) 2014
 *
 * Brick Yang <printfxxx@163.com>
 *
 * This program is free software. You can redistribute it and/or
 * modify it as you like.
 */

/**
 * @file	mtrace.h
 * @brief	Header file for mtrace
 */

#ifndef _MTRACE_H_
#define _MTRACE_H_

#ifdef MTRACE

int mtrace_init(void);
void mtrace_finish(void);

#ifdef __KERNEL__

#define MTRACE_KMEM_ADD(p)		(_mtrace_kmem_add((long)p, __func__, __LINE__) ? (kfree(p), p = NULL, -ENOMEM) : 0)
#define MTRACE_KMEM_DEL(p)		_mtrace_kmem_del((long)p, __func__, __LINE__)
#define MTRACE_VMEM_ADD(p)		(_mtrace_vmem_add((long)p, __func__, __LINE__) ? (vfree(p), p = NULL, -ENOMEM) : 0)
#define MTRACE_VMEM_DEL(p)		_mtrace_vmem_del((long)p, __func__, __LINE__)
#define MTRACE_DEVM_ADD(p, d)		(_mtrace_devm_add((long)p, __func__, __LINE__) ? (devm_kfree(d, p), p = NULL, -ENOMEM) : 0)
#define MTRACE_DEVM_DEL(p)		_mtrace_devm_del((long)p, __func__, __LINE__)
#define MTRACE_DMACOH_ADD(p, d, s, b)	(_mtrace_dmacoh_add((long)p, __func__, __LINE__) ? (dma_free_coherent(d, s, p, b), p = NULL, -ENOMEM) : 0)
#define MTRACE_DMACOH_DEL(p)		_mtrace_dmacoh_del((long)p, __func__, __LINE__)
#define MTRACE_SKB_ADD(p)		(_mtrace_skb_add((long)p, __func__, __LINE__) ? (kfree_skb(p), p = NULL, -ENOMEM) : 0)
#define MTRACE_SKB_DEL(p)		_mtrace_skb_del((long)p, __func__, __LINE__)
#define MTRACE_PERCPU_ADD(p)		(_mtrace_percpu_add((long)p, __func__, __LINE__) ? (free_percpu(p), p = NULL, -ENOMEM) : 0)
#define MTRACE_PERCPU_DEL(p)		_mtrace_percpu_del((long)p, __func__, __LINE__)

int _mtrace_kmem_add(long addr, const char *name, int line);
void _mtrace_kmem_del(long addr, const char *name, int line);
int _mtrace_vmem_add(long addr, const char *name, int line);
void _mtrace_vmem_del(long addr, const char *name, int line);
int _mtrace_devm_add(long addr, const char *name, int line);
void _mtrace_devm_del(long addr, const char *name, int line);
int _mtrace_dmacoh_add(long addr, const char *name, int line);
void _mtrace_dmacoh_del(long addr, const char *name, int line);
int _mtrace_skb_add(long addr, const char *name, int line);
void _mtrace_skb_del(long addr, const char *name, int line);
int _mtrace_percpu_add(long addr, const char *name, int line);
void _mtrace_percpu_del(long addr, const char *name, int line);

#else	/* __KERNEL__ */

#define MTRACE_MEM_ADD(p)	(_mtrace_mem_add((long)p, __func__, __LINE__) ? (free(p), p = NULL, ENOMEM) : 0)
#define MTRACE_MEM_DEL(p)	_mtrace_mem_del((long)p, __func__, __LINE__)

int _mtrace_mem_add(long addr, const char *name, int line);
void _mtrace_mem_del(long addr, const char *name, int line);

#endif	/* __KERNEL__ */

#else	/* MTRACE */

static inline int mtrace_init(void)
{
	return 0;
}

static inline void mtrace_finish(void)
{
}

#ifdef __KERNEL__

#define MTRACE_KMEM_ADD(p)		(0)
#define MTRACE_KMEM_DEL(p)		do { } while (0)
#define MTRACE_VMEM_ADD(p)		(0)
#define MTRACE_VMEM_DEL(p)		do { } while (0)
#define MTRACE_DEVM_ADD(p, d)		(0)
#define MTRACE_DEVM_DEL(p)		do { } while (0)
#define MTRACE_DMACOH_ADD(p, d, s, b)	(0)
#define MTRACE_DMACOH_DEL(p)		do { } while (0)
#define MTRACE_SKB_ADD(p)		(0)
#define MTRACE_SKB_DEL(p)		do { } while (0)
#define MTRACE_PERCPU_ADD(p)		(0)
#define MTRACE_PERCPU_DEL(p)		do { } while (0)

#else	/* __KERNEL__ */

#define MTRACE_MEM_ADD(p)		(0)
#define MTRACE_MEM_DEL(p)		do { } while (0)

#endif	/* __KERNEL__ */

#endif	/* MTRACE */

#endif	/* _MTRACE_H_ */
